import { defineStore } from 'pinia';
import { CookieRef, AsyncData } from '#app';
import { StorageSerializers, useStorage } from '@vueuse/core';
import { Menu } from '~~/types/menu.d';

export default defineStore('auth', () => {
  // 需要服务端渲染就需要使用cookie才能在服务端获取到
  // const token: CookieRef<string | null> = useCookie('auth.token', {
  //   default: () => null,
  // });

  const accessToken = useLocalStorage('auth.accessToken', null, {
    serializer: StorageSerializers.string,
  });
  const refreshToken = useLocalStorage('auth.refreshToken', null, {
    serializer: StorageSerializers.string,
  });
  // console.log('🚀 ~ file: useAuth.ts:8 ~ defineStore ~ token:', token.value);

  // const user: Ref<object | null> = ref(null);
  interface User {
    name: string;
    roles: string[];
    menus: string[];
  }

  const user = <AsyncData<User, Error | null>>useAsyncData(
    '/auth/user',
    async function () {
      // 验证token是否有效
      // try {
      // consola.info('auth.refresh', token.value);

      if (accessToken.value) {
        const res = await $fetchApi('/auth/user', {
          // query: {
          // t: 1,
          // },
          // headers: {
          //   // token: token.value,
          //   a: '66666',
          // },
          // default: () => null,
        });
        // console.log('🚀 ~ file: useAuth.ts:34 ~ res:', res);
        // if (res) {
        //   // user.value = res;
        //   return res;
        // }
        return res;
      }

      // throw new Error('token is null')
      return null;
      // reset();
      // } catch (error) {
      //   // console.log('🚀 ~ file: useAuth.ts:47 ~ error:', error);
      //   setToken(null);
      //   throw error;
      // }
    },
    {
      default: () => null,
      watch: [accessToken],
      // immediate:false,
    },
  );
  watchAsyncDataError(user);

  watchEffect(() => {
    if (user.error.value) {
      // console.log(
      //   '🚀 ~ file: useAuth.ts:67 ~ watch ~ error:',
      //   user.error.value,
      // );
      accessToken.value = null;
      refreshToken.value = null;
    }
  });
  // console.log('🚀 ~ file: useAuth.ts:56 ~ defineStore ~ token:', token.value);
  // function setToken(newtoken: string | null) {
  //   token.value = newtoken;
  // }

  function reset() {
    // setToken(null);
    accessToken.value = null;
    refreshToken.value = null;
    // user.refresh();
  }

  // 登录改为普通的异步函数，user.pending现在只表示正在刷新用户信息，不再表示正在登陆，正在登录状态改为登录页自行控制。
  async function signIn(type: string, body?: any) {
    const res = <{ accessToken: string; refreshToken: string }>(
      await $fetchApi(`/auth/signIn/${type}`, {
        method: 'post',
        body: body,
      })
    );
    switch (type) {
      case 'password': {
        refreshToken.value = res.refreshToken;
        accessToken.value = res.accessToken;
        return true;
      }
      default: {
        throw new Error('未知的登录方式');
      }
    }
  }

  // 刷新用户信息;
  async function fetchUser() {
    await user.refresh();
    return user.data;
  }

  // 退出登录
  async function signOut() {
    try {
      await $fetchApi('/auth/signOut');
    } finally {
      reset();
    }
  }

  // 等待用户信息加载完毕，在某些需要在页面初始化时就要获取用户信息时使用。
  async function useUser() {
    // return (await user).data;
    // if (user.pending.value) {
    //   await new Promise((resolve, reject) => {
    //     watchOnce(user.pending, () => resolve);
    //   });
    // }
    await useAsyncDataNextTick(user);

    return user.data;
  }
  // console.log('🚀 ~ file: auth.ts:76 ~ useAuthStore ~ auth:', auth.data);

  // watch(token, (token) => {
  //   // console.log('🚀 ~ file: useAuth.ts:106 ~ watch ~ token:', token);
  //   if (!token) {
  //     // navigateTo({
  //     //   replace: true,
  //     //   path: '/signIn',
  //     //   query: {
  //     //     callback: useRoute().fullPath,
  //     //   },
  //     // });
  //   }
  // });

  // console.log(
  //   '🚀 ~ file: useAuth.ts:133 ~ defineStore ~ token.value:',
  //   token.value,
  // );

  function hasRole(key: string) {
    if (user.data.value) {
      return user.data.value.roles.indexOf(key) !== -1;
    }
    return false;
  }

  function hasMenu(key: string) {
    // if (hasRole('admin')) {
    //     return true;
    //   }

    // if (user.data.value) {
    const isAdmin = user.data.value?.menus.includes('admin');
    const t = key.replaceAll(/[^&|()]+/g, (s) => {
      return String(Boolean(isAdmin || user.data.value?.menus.includes(s)));
    });
    return !!eval(t);

    // return isAdmin || user.data.value?.menus.includes(key);
    // }
    // return false;
  }

  async function executeRefreshToken() {
    if (!refreshToken.value) {
      throw createError({
        statusCode: 401,
        statusMessage: 'refreshToken不存在',
        // request,
        // response,
        // options,
      });
    }

    try {
      const res = <{ token: string }>await $fetchApi('/auth/refreshToken', {
        method: 'POST',
        body: {
          refreshToken: refreshToken.value,
        },
        headers: {},
        isRefreshToken: true,
        // query:
      });
      accessToken.value = res.token;
    } catch (error) {
      // accessToken.value = null;
      // refreshToken.value = null;
      throw error;
    }
  }
  // const hasMenu = computed(() => {
  //   return { a: 66 };
  //   return (key: string) => {
  //     if (auth.data.value) {
  //       return auth.data.value.menus.indexOf(key) !== -1;
  //     }
  //     return false;
  //   };
  // });

  return {
    accessToken,
    refreshToken,
    user: user.data,
    pending: user.pending,
    error: user.error,
    signIn,
    fetchUser,
    signOut,
    useUser,
    raw: user,
    hasMenu,
    hasRole,
    executeRefreshToken,
    reset,
  };
});
